RXDbase: A NetRexx DB class implementation 1.0 - Max Marsiglietti 1996,97.
This is the official RXDbase documentation. You'll find here all the
informations you need for using the RXDbase library for NetRexx.
To get best results in visualization of this document, use a monospaced font.
English is not my language, as ever. :)
INDEX:
1.... Introduction
1.1. - What is RXDbase.
2.... Use of the RXDbase class
2.1 - in Java.
2.2 - in NetRexx.
2.3 - A detailed explanation of all the methods.
2.3.2 ** RXDbase constructors in NetRexx **
2.3.3 ** The CONNECT command **
2.3.4 ** The DISCONNECT command **
2.3.5 ** The STATUS command **
2.3.6 ** The SAVEREC command **
2.3.7 ** The LOADREC command **
2.3.8 ** The MODIREC command **
2.3.9 ** The DELEREC command **
2.3.10 ** The GETDBINFO command **
2.3.11 ** The GETDBSTATS command **
2.3.12 ** The DELETEDB command **
2.3.13 ** The GLOBALREBUILDIDX command **
2.3.14 ** The REBUILDIDX command **
2.3.15 ** The ADDFIELD command **
2.3.16 ** The DELFIELD command **
2.3.17 ** The MODFIELDIDX command **
2.3.18 ** The PACK command **
2.3.19 ** The GETDBSTATUS command **
2.3.20 ** The DEFINEFILTER command **
2.3.21 ** The LOADRECWITHFILTER command **
2.3.22 ** The MODFIELDNAME command **
2.3.23 ** The MODFIELDLENGTH command **
3.... Other stuff
3.1 - This package contents.
3.2 - License.
3.3 - Contacting the author.
3.4 - Release History.
1. I N T R O D U C T I O N
--------------------------
Notice: NetRexx, OS/2 are copyright of IBM Corp.
JAVA is a copyright of SUN Microsystems, Inc.
Other trademarks in this document are owned by the respective companies.
Whatever. :)
NetRexx is a great language, promising to be a 'better Java than Java';
it lacks nonetheless the file I/O APIs.
That's why I've started some months ago to develop RXFile, a NetRexx class
that implements linein, stream, chars and all the rest, plus some other
bonuses. Opening and closing files all day long is anyway no great fun;
there is the need to have a little database handy for all those situations
where JDBC is overkill. Why not to do it directly in NetRexx, then?
1.1 What is RXDbase.
--------------------
My goal is to provide a simple yet efficient database class which will have
the following features:
*) Fixed length fields (this feat may be removed by popular demand).
*) ISAM and B+Tree indexing.
*) string-oriented.
*) easy to use.
I did drop the following feature:
*) will have some tools to link a dbase to another (i.e. client + article = sale)
Because I plan to insert it into a separate package, to make them better than a timid
attempt to link a couple of databases.
It requires RXFile up-to-date, but one copy of this latter is always distributed
with the RXDbase package; it can be used both from Java (by installing the NetRexx
classes) that from NetRexx (NetRexx is really a translator that generates Java code).
If you ask me what of the two to use, I'll tell you 'NetRexx'.
Check by yourself at http://www2.hursley.ibm.com/netrexx/
2. U S E O F T H E R X D B A S E C L A S S
----------------------------------------------
2.1 In JAVA:
------------
Just make sure that your Java environment variables
knows where RXDbase.class is stored, then you can just
add this line to your source:
import RXDbase;
along with the required NetRexx imports.
2.2 In NetRexx:
---------------
import RXDbase
Is required in your NetRexx source file.
2.3 A detailed explanation of all the methods.
----------------------------------------------
Why did I state 'methods', and not also 'properties' or 'exceptions' ?
Simply put, the RXDbase class has no public properties (variables),
and doesn't throw exceptions. Instead, it has methods to find out
if there have been errors, and to query the value of some properties.
2.3.1 Before we begin
---------------------
Warning: in this version (0.4) I have changed the syntax of most functions.
This was done because I've added indexes; a great amount of new code has
been written, and while I've managed to keep this package very simple to
use, I had nonetheless to change something also at functions level.
If I can, I'll try not to change anymore the syntax of the functions in
the future; I am pretty confident to succeed, since only a few things
are missing from the code base.
The data format also has changed, so you can't migrate your existing database
to this new release format. I _promise_ not to change this format anymore.
Update: As of release 0.55 I had to change the file format of the RXDbase, because the RXDbase itself has completed the beta stage. RXDbase was given to an Italian firm which produces OS/2 software - it will be included in a commercial package.
But since RXDbase was derived from a Rexx library that I developed some years ago independently from that firm, I am now porting directly that library, while maintaining the RXDbase syntax and structures. The only thing that will change is the file format, and this already happened it this release. Speaking about file format you will notice that starting from this release I have dropped the use of a .def file, and I don't plan to return to it since the new file format works better without. One advantage of the new file format is that the database can be seen more easily by the programs that can read ascii databases, such as StarOffice from Star Division.
Update: As of release 0.81 I had to change the file format - once again - to accomodate for the presence
on two new features: NO NULLS and NO DUPLICATES.
Note: As you may know, the newline sequence is not standard among the operating
systems. I.e., in Unix it's \n, in DOS-Win-OS/2 is \r\n, in Macs is \r etc.
Since the RXDbase format is something like:
Y:N|field|..|field<newline>
[Where 'Y' at the begin of the line means that the record is valid, and
'N' means that the record is currently about to be discarded (it is
marked as deleted)]
You may think you have to care about what <newline> you will have to use;
the answer is no, RXDbase automatically sets the correct newline
(currently \n, \r and \r\n are supported, since I know of these) for your system.
Cute heh?
Limitations:
*) you cannot have currently more than 1000 fields in a record [upped from 256].
*) you have to have at least an index, but you can choose the type (ISAM or B+Tree).
(Current limitation: only the ISAM indexing has been implemented)
*) still to do: B+Tree indexing, some neat 'search' function, expanding
the docs/examples, providing a function to correct errors in the
database.
In this document all the calls are documented with Java parameter/return
convention. You should be able to guess the correspondant NetRexx syntax.
If you need more help, look at the examples.
A note about names:
a database is a collection of records, a record is a collection of fields.
the whole database
------------|-------------
/ \
-------------+-------------+
Massimiliano | Marsiglietti| <--- A record (_that_ person)
-------------+-------------|
Cristina | Severi |
-------------+-------------+
|
\---- A field (name of a person)
2.3.2 ** RXDbase constructors in NetRexx **
-------------------------------------------
Note that the semicolon is optional:
MyDB = RXDbase();
or
MyDB = RXDbase(Rexx rName, Rexx[][] rRec)
MyDB = RXDbase(Rexx rName)
The above two constructors works as in the CONNECT command.
The default return strings for the following functions are:
DBNOTSTARTED: (can't work on nothing)
READY: (no errors)
SYNTAX ERROR: (go figure)
ERROR:FILE ACCESS PROBLEMS (something weird at file level)
Unless stated otherwise. More error codes will be introduced as
the RXDbase will be enhanced.
2.3.3 ** The CONNECT command **
---------------------------------
This command is the very first to issue, if you have not instantiated
an RXDbase variable with the two-parameters or one-parameter constructor.
If you have, you can omit this command.
Syntax:
Rexx connect(Rexx rName, Rexx[][] rRec)
Where:
rName is the name of the file _without_any_extension_ that is
hosting/will host the database on the disk.
RXDbase will add the file name extension '.dat' to this name.
rRec is a bi-dimensional Rexx array that has to be built this way:
rRec[0][0] --> Number of fields in the database.
rRec[n][0] --> Length (a whole number stored in a Rexx variable) of field 'n'.
rRec[n][1] --> Name of field 'n' (it will be used later).
rRec[n][2] --> Indexing method of the field: it can be any of the following:
ISAM = Indexed Sequential Access Method, good if you need
to work on the database ordered on this field.
B+TREE = Balanced binary tree. Useful if you need to look
for a single item quickly. NOT YET IMPLEMENTED.
NONE = when you don't do much operations on this field.
More on the indexing: if you want a field not to allow null values or duplicate
values, you should append an '1' or a '0' to the indexing string like here:
ISAM00 = ISAM indexing, duplicate and null values are allowed.
ISAM11 = ISAM indexing, duplicate and null values are NOT allowed.
ISAM10 = ISAM indexing, duplicate values are NOT allowed, null values are.
ISAM01 = ISAM indexing, duplicate values are allowed, null values are NOT.
NONE0 = No indexing, null values are allowed.
NONE1 = No indexing, null values are NOT allowed.
As you may have noticed, you cannot specify 'no duplicate values' for the
no-index strategy of indexing.
Notes:
*) you cannot have currently more than 1000 fields in a record.
*) you have to have at least an index, but you can choose the type (ISAM or B+Tree).
(Current limitation: only the ISAM indexing has been implemented)
*) when you create a database, several files will be created.
One, .dat is the real data base; then, you have a file for every index.
This was done for speed.
Syntax:
Rexx connect(Rexx rName)
This command simply connects to an existing database.
2.3.4 ** The DISCONNECT command **
------------------------------------
Simply put, this command closes all the db activities for the
database being used.
Syntax:
Rexx disconnect()
2.3.5 ** The STATUS command **
--------------------------------
With this command, you can query the internal status of
the database (ready, dbnotstarted, etc).
Syntax:
Rexx status()
2.3.6 ** The SAVEREC command **
---------------------------------
This command lets you write a record on disk.
All of the indexes are automatically updated.
Syntax:
Rexx saverec(Rexx[][] rToSave, Rexx rMode)
Where rMode can only be 'overwrite' or 'append' (case isn't
significative).
rToSave is to be built this way:
rToSave[0,0] --> number of records to be written.
rToSave[n,m] --> field n of record m.
Warning: both n,m are to start from 1 (one).
Warning: When you specify 'overwrite', _the_whole_database_
will be overwritten (deleted), and the indexes will be resetted.
Returns:
An appropriate error message is shown in case of errors, else you
will be returned a Rexx string, in which every character is
either '0' or '1', where '0' means that the specified record
was not succesfully saved (a null value where nulls weren't allowed,
or a duplicate value where there sholdn't be any) and a '1' means
that the record was saved succesfully.
The position of the character is corresponding to the passed record
number, ie if I try to save 3 record and I get '010', that means
that only the 2-nd record among the ones passed to SAVEREC was saved
succesfully.
2.3.7 ** The LOADREC command **
---------------------------------
Loadrec loads in memory a number of records from the